package com.chen.service.impl;

import cn.hutool.core.lang.Snowflake;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chen.domain.EntrustOrder;
import com.chen.domain.Market;
import com.chen.dto.AccountDto;
import com.chen.fegin.AccountFegin;
import com.chen.mapper.EntrustOrderMapper;
import com.chen.model.EntrustOrderParam;
import com.chen.service.EntrustOrderService;
import com.chen.service.MarketService;
import com.chen.utils.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Service
public class EntrustOrderServiceImpl extends ServiceImpl<EntrustOrderMapper, EntrustOrder> implements EntrustOrderService{

    @Autowired
    private MarketService marketService;

    @Resource
    private AccountFegin accountFegin;

    private Snowflake snowflake = new Snowflake(5,1);


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void buy(EntrustOrderParam entrustOrderParam) {

        //获取用户的总交易buycoin的数量
        BigDecimal allPrcice = new BigDecimal(entrustOrderParam.getVolume()).multiply(new BigDecimal(entrustOrderParam.getPrice()));

        Market market = marketService.getOne(new LambdaQueryWrapper<Market>()
                .eq(Market::getSymbol, entrustOrderParam.getSymbol()));
        //单笔委托量
        if(new BigDecimal(entrustOrderParam.getVolume()).compareTo(market.getNumMin()) < 0){
           throw new IllegalArgumentException("当前委托单小于最小委托量");
        }
        if(new BigDecimal(entrustOrderParam.getVolume()).compareTo(market.getNumMax()) > 0){
            throw new IllegalArgumentException("当前委托单大于最大委托量");
        }

        //判断用户资金是否足够
        AccountDto accountDto = accountFegin.getUserAccountByCoinId(market.getBuyCoinId(), UserUtil.getUser());
        if(accountDto.getBalanceAmount().compareTo(allPrcice)<0){
            throw new IllegalArgumentException("用户的可用余额不足");
        }

        //构建对象
        EntrustOrder entrustOrder = new EntrustOrder();
        entrustOrder.setAmount(new BigDecimal(entrustOrderParam.getVolume()));
//        entrustOrder.setBaseCoinRate();
//        entrustOrder.setContractUnit();
        entrustOrder.setCreated(new Date());
        entrustOrder.setDeal(BigDecimal.ZERO);

        entrustOrder.setFee(allPrcice.multiply(market.getFeeBuy()));
        entrustOrder.setFeeRate(market.getFeeBuy());
        entrustOrder.setFreeze(allPrcice);
        entrustOrder.setLastUpdateTime(new Date());
        entrustOrder.setLockMargin(BigDecimal.ZERO);
        entrustOrder.setMarginRate(BigDecimal.ZERO);
        entrustOrder.setMarketId(market.getId());
        entrustOrder.setMarketName(market.getName());
        entrustOrder.setMarketType(market.getType());

        String depth = market.getMergeDepth();
        List<String> depthList = Arrays.asList(depth.split(","));
        Collections.sort(depthList);

        int i = Integer.parseInt(depthList.get(0));
        //直接删除多余的小数位，如2.35会变成2.3 setScale(1,BigDecimal.ROUND_DOWN)
        BigDecimal deptVoLow = new BigDecimal(entrustOrderParam.getPrice()).setScale(i, BigDecimal.ROUND_DOWN);

        int p = Integer.parseInt(depthList.get(2));
        BigDecimal deptVoHig = new BigDecimal(entrustOrderParam.getPrice()).setScale(p, BigDecimal.ROUND_DOWN);

        entrustOrder.setMergeHighPrice(deptVoHig);
        entrustOrder.setMergeLowPrice(deptVoLow);
        entrustOrder.setPrice(new BigDecimal(entrustOrderParam.getPrice()));
        entrustOrder.setPriceType((byte)2);
        entrustOrder.setStatus((byte)0);
        entrustOrder.setSymbol(entrustOrderParam.getSymbol());
        entrustOrder.setType((byte)1);
        entrustOrder.setId(snowflake.nextId());
        entrustOrder.setUserId(UserUtil.getUser());
        entrustOrder.setVolume(new BigDecimal(entrustOrderParam.getVolume()));
        save(entrustOrder);

        //将用户的 buy coinId -》 可用余额 转入冻结余额

        Boolean aBoolean = accountFegin.transferUserLock(market.getBuyCoinId(), UserUtil.getUser(), allPrcice, entrustOrder.getId());
        if(!aBoolean){
            throw new IllegalArgumentException("用户资金转入冻结失败");
        }


    }
}
